package de.mrapp.ohos_util;

import de.mrapp.util.Condition;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.global.resource.Element;
import ohos.global.resource.NotExistException;
import ohos.global.resource.solidxml.Theme;
import ohos.global.resource.solidxml.TypedAttribute;

/**
 * An utility class, which provides static methods for retrieving theme attributes.
 */
public class ThemeUtil {

    /**
     * Obtains the attribute, which corresponds to a specific resource id, from a theme.
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return A type array, which holds the attribute, which has been obtained, as an instance of
     */
    private static TypedAttribute obtainStyledAttributes(final Context context,
                                                     final int themeResourceId,
                                                     final int resourceId) {
        Condition.INSTANCE.ensureNotNull(context, "The context may not be null");
        Theme theme = context.getTheme();
        String[] attrs = new String[]{themeResourceId+""};

        return theme.getThemeHash(attrs).get(resourceId);

    }

    /**
     * Creates a new utility class, which provides static methods for retrieving theme attributes.
     */
    private ThemeUtil() {

    }

    /**
     * Obtains the color, which corresponds to a specific resource id, from a context's theme. If
     * the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The color, which has been obtained, as an {@link Integer} value
     */
    public static int getColor(final Context context,final int resourceId) {
        return getColor(context, -1, resourceId);
    }

    /**
     * Obtains the color, which corresponds to a specific resource id, from a specific theme. If the
     * given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The color, which has been obtained, as an {@link Integer} value
     */
    public static int getColor(final Context context,final int themeResourceId,
                               final int resourceId) {
        TypedAttribute typedAttribute = null;
        int color = 0 ;

        try {
            typedAttribute = obtainStyledAttributes(context, themeResourceId, resourceId);
            color = typedAttribute.getColorValue();

            if (color == -1) {
                int id = typedAttribute.getResId();
                color = context.getColor(id);

                if (color == 0) {
                    throw new NotExistException(
                            "Resource ID #0x" + Integer.toHexString(resourceId) + " is not valid");
                }
            }

            return color;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (typedAttribute != null) {
                typedAttribute = null;
            }
        }
        return color;
    }

    /**
     * Obtains the color state list, which corresponds to a specific resource id, from a context's
     * theme. If the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The color state list, which has been obtained, as an instance of the class
     */
    public static Color getColorStateList(final Context context,
                                          final int resourceId) {
        //ohos 暂时还没有获取ColorStateList的api,目前只获取color
        return getColorStateList(context, -1, resourceId);
    }

    /**
     * Obtains the color state list, which corresponds to a specific resource id, from a specific
     * theme. If the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The color state list, which has been obtained, as an instance of the class
     */
    public static Color getColorStateList(final Context context,
                                                   final int themeResourceId,
                                                   final int resourceId) {
        //ohos 暂时还没有获取ColorStateList的api,目前只获取color
//        TypedAttribute TypedAttribute = null;
//
//        try {
//            TypedAttribute = obtainStyledAttributes(context, themeResourceId, resourceId);
//            ColorStateList colorStateList = TypedAttribute.getColorStateList(0);
//
//            if (colorStateList == null) {
//                throw new NotFoundException(
//                        "Resource ID #0x" + Integer.toHexString(resourceId) + " is not valid");
//            }
//
//            return colorStateList;
//        } finally {
//            if (TypedAttribute != null) {
//                TypedAttribute.recycle();
//            }
//        }
//        return getColor(context , themeResourceId , resourceId);
        return null;
    }

    /**
     * Obtains the string, which corresponds to a specific resource id, from a context's theme. If
     * the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The string, which has been obtained, as a {@link String}
     */
    public static String getString(final Context context, final int resourceId) {
        return getString(context, -1, resourceId);
    }

    /**
     * Obtains the string, which corresponds to a specific resource id, from a specific theme. If
     * the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The string, which has been obtained, as a {@link String}
     */
    public static String getString(final Context context,
                                   final int themeResourceId,
                                   final int resourceId) {
        Condition.INSTANCE.ensureNotNull(context, "The context may not be null");
        TypedAttribute typedAttribute = null;
        String stringValue = "";

        try {
            typedAttribute = obtainStyledAttributes(context, themeResourceId, resourceId);
            stringValue = typedAttribute.getStringValue();
            if (stringValue == null) {
                throw new NotExistException(
                        "Resource ID #0x" + Integer.toHexString(resourceId) + " is not valid");
            }

            return stringValue;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (typedAttribute != null) {
                typedAttribute = null;
            }
        }
        return stringValue;
    }

    /**
     * Obtains the text, which corresponds to a specific resource id, from a context's theme. If the
     * given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The text, which has been obtained, as an instance of the type {@link CharSequence}
     */
    public static CharSequence getText(final Context context,
                                       final int resourceId) {
        return getText(context, -1, resourceId);
    }

    /**
     * Obtains the text, which corresponds to a specific resource id, from a specific theme. If the
     * given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The text, which has been obtained, as an instance of the type {@link CharSequence}
     */
    public static CharSequence getText(final Context context,
                                       final int themeResourceId,
                                       final int resourceId) {
        //ohos 暂时还没有获取text的api
//        TypedAttribute typedAttribute = null;
//        try {
//            typedAttribute = obtainStyledAttributes(context, themeResourceId, resourceId);
//            CharSequence text = TypedAttribute.getText(0);
//            if (text == null) {
//                throw new NotFoundException(
//                        "Resource ID #0x" + Integer.toHexString(resourceId) + " is not valid");
//            }
//
//            return text;
//        } finally {
//            if (TypedAttribute != null) {
//                TypedAttribute.recycle();
//            }
//        }
        return null;
    }

    /**
     * Obtains the text array, which corresponds to a specific resource id, from a context's theme.
     * If the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The text array, which has been obtained, as an instance of the type {@link
     * CharSequence}
     */
    public static CharSequence[] getTextArray(final Context context,
                                              final int resourceId) {
        return getTextArray(context, -1, resourceId);
    }

    /**
     * Obtains the text array, which corresponds to a specific resource id, from a specific theme.
     * If the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The text array, which has been obtained, as an array of the type {@link CharSequence}
     */
    public static CharSequence[] getTextArray(final Context context,
                                              final int themeResourceId,
                                              final int resourceId) {
        //ohos 暂时还没有获取textArray的api
//        TypedAttribute typedAttribute = null;
//
//        try {
//            typedAttribute = obtainStyledAttributes(context, themeResourceId, resourceId);
//            CharSequence[] textArray = TypedAttribute.getTextArray(0);
//
//            if (textArray == null) {
//                throw new NotFoundException(
//                        "Resource ID #0x" + Integer.toHexString(resourceId) + " is not valid");
//            }
//
//            return textArray;
//        } finally {
//            if (TypedAttribute != null) {
//                TypedAttribute.recycle();
//            }
//        }
        return null;
    }

    /**
     * Obtains the dimension, which corresponds to a specific resource id, from a context's theme.
     * If the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The dimension, which has been obtained, as a {@link Float} value
     */
    public static float getDimension(final Context context,
                                     final int resourceId) {
        return getDimension(context, -1, resourceId);
    }

    /**
     * Obtains the dimension, which corresponds to a specific resource id, from a specific theme. If
     * the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The dimension, which has been obtained, as a {@link Float} value
     */
    public static float getDimension(final Context context,
                                     final int themeResourceId,
                                     final int resourceId) {
        TypedAttribute typedAttribute = null;
        float dimension = 0 ;

        try {
            typedAttribute = obtainStyledAttributes(context, themeResourceId, resourceId);
            dimension = typedAttribute.getFloatValue();
            if (dimension == -1) {
                throw new NotExistException(
                        "Resource ID #0x" + Integer.toHexString(resourceId) + " is not valid");
            }

            return dimension;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (typedAttribute != null) {
                typedAttribute = null;
            }
        }
        return dimension;
    }

    /**
     * Obtains the dimension pixel size, which corresponds to a specific resource id, from a
     * context's theme. If the given resource id is invalid
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The dimension pixel size, which has been obtained, as an {@link Integer} value
     */
    public static int getDimensionPixelSize(final Context context,
                                            final int resourceId) {
        return getDimensionPixelSize(context, -1, resourceId);
    }

    /**
     * Obtains the dimension pixel size, which corresponds to a specific resource id, from a
     * specific theme. If the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The dimension pixel size, which has been obtained, as an {@link Integer} value
     */
    public static int getDimensionPixelSize(final Context context,
                                            final int themeResourceId,
                                            final int resourceId) {
        TypedAttribute typedAttribute = null;
        int dimension = 0 ;

        try {
            typedAttribute = obtainStyledAttributes(context, themeResourceId, resourceId);
            dimension = typedAttribute.getPixelValue(true);

            if (dimension == -1) {
                throw new NotExistException(
                        "Resource ID #0x" + Integer.toHexString(resourceId) + " is not valid");
            }

            return dimension;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (typedAttribute != null) {
                typedAttribute = null;
            }
        }
        return dimension;
    }

    /**
     * Obtains the dimension pixel offset, which corresponds to a specific resource id, from a
     * context's theme. If the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The dimension pixel offset, which has been obtained, as an {@link Integer} value
     */
    public static int getDimensionPixelOffset(final Context context,
                                              final int resourceId) {
        return getDimensionPixelSize(context, -1, resourceId);
    }

    /**
     * Obtains the dimension pixel offset, which corresponds to a specific resource id, from a
     * specific theme. If the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The dimension pixel offset, which has been obtained, as an {@link Integer} value
     */
    public static int getDimensionPixelOffset(final Context context,
                                              final int themeResourceId,
                                              final int resourceId) {
        return getDimensionPixelSize(context, themeResourceId, resourceId);
    }

    /**
     * Obtains the drawable, which corresponds to a specific resource id, from a context's theme. If
     * the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The drawable, which has been obtained, as an instance of the class {@link Element}
     */
    public static Element getDrawable(final Context context,
                                      final int resourceId) {
        return getDrawable(context, -1, resourceId);
    }

    /**
     * Obtains the drawable, which corresponds to a specific resource id, from a specific theme. If
     * the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The drawable, which has been obtained, as an instance of the class {@link Element}
     */
    public static Element getDrawable(final Context context,
                                       final int themeResourceId,
                                       final int resourceId) {
        TypedAttribute typedAttribute = null;
        Element element = null;

        try {
            typedAttribute = obtainStyledAttributes(context, themeResourceId, resourceId);
            int drawableId = typedAttribute.getResId();
            element = typedAttribute.getResourceManager().getElement(drawableId);

            if (element == null || (drawableId != -1)) {
                throw new NotExistException(
                        "Resource ID #0x" + Integer.toHexString(resourceId) + " is not valid");
            }

            return element;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (typedAttribute != null) {
                typedAttribute = null;
            }
        }
        return null;
    }

    /**
     * Obtains the fraction, which corresponds to a specific resource id, from a context's theme. If
     * the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @param base
     *         The base value of this fraction as an {@link Integer} value. A standard fraction is
     *         multiplied by this value
     * @param pbase
     *         The parent base value of this fraction as an {@link Integer} value. A parent fraction
     *         (nn%p) is multiplied by this value
     * @return The fraction, which has been obtained, as a {@link Float} value
     */
    public static float getFraction(final Context context, final int resourceId,
                                    final int base, final int pbase) {
        return getFraction(context, -1, resourceId, base, pbase);
    }

    /**
     * Obtains the fraction, which corresponds to a specific resource id, from a specific theme. If
     * the given resource id is invalid
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @param base
     *         The base value of this fraction as an {@link Integer} value. A standard fraction is
     *         multiplied by this value
     * @param pbase
     *         The parent base value of this fraction as an {@link Integer} value. A parent fraction
     *         (nn%p) is multiplied by this value
     * @return The fraction, which has been obtained, as a {@link Float} value
     */
    public static float getFraction(final Context context,
                                    final int themeResourceId,
                                    final int resourceId, final int base,
                                    final int pbase) {
        TypedAttribute typedAttribute = null;
        float fraction = 0 ;

        try {
            typedAttribute = obtainStyledAttributes(context, themeResourceId, resourceId);
            fraction = typedAttribute.getFloatValue();

            if (fraction == -1) {
                throw new NotExistException(
                        "Resource ID #0x" + Integer.toHexString(resourceId) + " is not valid");
            }

            return fraction;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (typedAttribute != null) {
                typedAttribute = null;
            }
        }
        return fraction;
    }

    /**
     * Obtains the boolean value, which corresponds to a specific resource id, from a specific
     * theme.
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @return The boolean value, which has been obtained, as a {@link Boolean} value or false, if
     * the given resource id is invalid
     */
    public static boolean getBoolean(final Context context,
                                     final int themeResourceId,
                                     final int resourceId) {
        TypedAttribute typedAttribute = null;
        try {
            typedAttribute = obtainStyledAttributes(context, themeResourceId, resourceId);
            return typedAttribute.getBooleanValue();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (typedAttribute != null) {
                typedAttribute = null;
            }
        }
        return false;
    }

    /**
     * Obtains the boolean value, which corresponds to a specific resource id, from a context's
     * theme.
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @param defaultValue
     *         The default value, which should be returned, if the given resource id is invalid, as
     *         a {@link Boolean} value
     * @return The boolean value, which has been obtained, as an {@link Boolean} value or false, if
     * the given resource id is invalid
     */
    public static boolean getBoolean(final Context context, final int resourceId,
                                     final boolean defaultValue) {
        return getBoolean(context, -1, resourceId, defaultValue);
    }

    /**
     * Obtains the boolean value, which corresponds to a specific resource id, from a specific
     * theme.
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @param defaultValue
     *         The default value, which should be returned, if the given resource id is invalid, as
     *         a {@link Boolean} value
     * @return The boolean value, which has been obtained, as a {@link Boolean} value or false, if
     * the given resource id is invalid
     */
    public static boolean getBoolean(final Context context,
                                     final int themeResourceId,
                                     final int resourceId, final boolean defaultValue) {
        TypedAttribute typedAttribute = null;

        try {
            typedAttribute = obtainStyledAttributes(context, themeResourceId, resourceId);
            return typedAttribute.getBooleanValue();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (typedAttribute != null) {
                typedAttribute = null;
            }
        }
        return false;
    }

    /**
     * Obtains the integer value, which corresponds to a specific resource id, from a context's
     * theme.
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @param defaultValue
     *         The default value, which should be returned, if the given resource id is invalid, as
     *         an {@link Integer} value
     * @return The integer value, which has been obtained, as an {@link Integer} value or 0, if the
     * given resource id is invalid
     */
    public static int getInt(final Context context, final int resourceId,
                             final int defaultValue) {
        return getInt(context, -1, resourceId, defaultValue);
    }

    /**
     * Obtains the integer value, which corresponds to a specific resource id, from a specific
     * theme.
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @param defaultValue
     *         The default value, which should be returned, if the given resource id is invalid, as
     *         an {@link Integer} value
     * @return The integer value, which has been obtained, as an {@link Integer} value or 0, if the
     * given resource id is invalid
     */
    public static int getInt(final Context context, final int themeResourceId,
                             final int resourceId, final int defaultValue) {
        TypedAttribute typedAttribute = null;

        try {
            typedAttribute = obtainStyledAttributes(context, themeResourceId, resourceId);
            return typedAttribute.getIntegerValue();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (typedAttribute != null) {
                typedAttribute = null;
            }
        }
        return 0;
    }

    /**
     * Obtains the float value, which corresponds to a specific resource id, from a context's
     * theme.
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @param defaultValue
     *         The default value, which should be returned, if the given resource id is invalid, as
     *         a {@link Float} value
     * @return The float value, which has been obtained, as a {@link Float} value or 0, if the given
     * resource id is invalid
     */
    public static float getFloat(final Context context, final int resourceId,
                                 final float defaultValue) {
        return getFloat(context, -1, resourceId, defaultValue);
    }

    /**
     * Obtains the float value, which corresponds to a specific resource id, from a specific theme.
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @param defaultValue
     *         The default value, which should be returned, if the given resource id is invalid, as
     *         a {@link Float} value
     * @return The float value, which has been obtained, as a {@link Float} value or 0, if the given
     * resource id is invalid
     */
    public static float getFloat(final Context context,
                                 final int themeResourceId, final int resourceId,
                                 final float defaultValue) {
        TypedAttribute typedAttribute = null;

        try {
            typedAttribute = obtainStyledAttributes(context, themeResourceId, resourceId);
            return typedAttribute.getFloatValue();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (typedAttribute != null) {
                typedAttribute = null;
            }
        }
        return 0;
    }

    /**
     * Obtains the resource id, which corresponds to a specific resource id, from a context's
     * theme.
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must corresponds to a valid theme attribute
     * @param defaultValue
     *         The default value, which should be returned, if the given resource id is invalid, as
     *         an {@link Integer} value
     * @return The resource id, which has been obtained, as an {@link Integer} value or 0, if the
     * given resource id is invalid
     */
    public static int getResId(final Context context, final int resourceId,
                               final int defaultValue) {
        return getResId(context, -1, resourceId, defaultValue);
    }

    /**
     * Obtains the resource id, which corresponds to a specific resource id, from a specific theme.
     *
     * @param context
     *         The context, which should be used, as an instance of the class {@link Context}. The
     *         context may not be null
     * @param themeResourceId
     *         The resource id of the theme, the attribute should be obtained from, as an {@link
     *         Integer} value or -1, if the attribute should be obtained from the given context's
     *         theme
     * @param resourceId
     *         The resource id of the attribute, which should be obtained, as an {@link Integer}
     *         value. The resource id must correspond to a valid theme attribute
     * @param defaultValue
     *         The default value, which should be returned, if the given resource id is invalid, as
     *         an {@link Integer} value
     * @return The resource id, which has been obtained, as an {@link Integer} value or 0, if the
     * given resource id is invalid
     */
    public static int getResId(final Context context, final int themeResourceId,
                               final int resourceId, final int defaultValue) {
        TypedAttribute typedAttribute = null;

        try {
            typedAttribute = obtainStyledAttributes(context, themeResourceId, resourceId);
            return typedAttribute.getResId();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (typedAttribute != null) {
                typedAttribute = null;
            }
        }
        return 0;
    }
}
